#ifndef	CLSV_H_
#define	CLSV_H_

#define TRUE	1
#define FALSE	!TRUE

/* macro to get the size of an encripted string */
#define	ESIZE(x)		((x)+8-(x)%8)

#define	MAX_DATA		512		/* max bytes in DATA_BLOCK */
#define	MAX_LIST		512		/* max bytes in LIST_BLOCK */
#define	MAX_FILENAME	126		/* max length for filename */
#define MAX_EFILENAME	MAX_FILENAME+2
#define	MAX_USER		25		/* max length for username */
#define	MAX_PASS		25		/* max length for password */
#define MAX_EPASS		MAX_PASS+7
#define	MAX_TICKET		32		/* max length for ticket id */
#define	MAX_ETICKET		MAX_TICKET+8
#define	MAX_CATEGORY	60		/* max length for category */
#define	MAX_OPCODES		32		/* max opcodes */

#define MAX_QSTRING		300		/* max query string */
#define	MAX_INT_LEN		11		
#define	MAX_DATAGRAM	65535	/* maximum bytes in a datagram */
#define MD5_SIZE		32		/* md5's size */

#define _TCP_		1			/* TCP */
#define _UDP_		2			/* UDP */

#define _DOWNLOAD_		1
#define _UPLOAD_		2

typedef short OPC;				/* Opcode's type */
typedef short STAT;				/* Opcode's stat */

/* Opcode definitions */
enum
{
	LOGIN, PASSWD, GET_TICKET, USE_TICKET, UPLOAD, LIST_CATEGORIES, 
	LIST_USERS,	LIST_FILES, DATA_BLOCK, LIST_BLOCK
};

/* Encapsulated packet definitions */

/* --------------------------------- CL->SV --------------------------------- */

typedef struct /* LOGIN */
{
	char user[MAX_USER+1];				/* username */
	char pass[MAX_EPASS];				/* password */
} CLSV_LOGIN;

typedef struct /* PASSWD */
{
	char user[MAX_USER+1];				/* username */
	char oldpass[MAX_EPASS];			/* old password */
	char newpass[MAX_EPASS];			/* new password */
} CLSV_PASSWD;

typedef struct	/* GET_TICKET */
{
	char user[MAX_USER+1];				/* user */
	char pass[MAX_EPASS];				/* password */
	char filename[MAX_EFILENAME];		/* filename */
} CLSV_GET_TICKET;

typedef struct /* USE_TICKET */
{
	char user[MAX_USER+1];				/* user */
	char pass[MAX_EPASS];				/* password */
	char ticket_id[MAX_ETICKET];		/* ticket's id */
} CLSV_USE_TICKET;

typedef struct /* UPLOAD */
{
	int size;							/* size in bytes */
	char filename[MAX_FILENAME+1];		/* filename */
} CLSV_UPLOAD;

typedef struct /* LIST_USERS */
{
	char user[MAX_USER+1];				/* user */
	char pass[MAX_EPASS];				/* password */
} CLSV_LIST_USERS;

typedef struct /* LIST FILES */
{
	char user[MAX_USER+1];				/* user */
	char pass[MAX_EPASS];				/* password */
	char category[MAX_CATEGORY+1];		/* category */
} CLSV_LIST_FILES;


/* --------------------------------- SV->CL --------------------------------- */

typedef struct /* LOGIN */
{
	STAT status;						/* status */
} SVCL_LOGIN;

typedef struct /* PASSWD */
{
	STAT status;						/* status */
} SVCL_PASSWD;

typedef struct /* GET_TICKET */
{
	STAT status;						/* status */
	int dtime;							/* deliver time */
	int etime;							/* enable time */
	int ftime;							/* expiration time */
	char id[MAX_ETICKET];				/* ticket's id */
} SVCL_GET_TICKET;

typedef struct /* UPLOAD */
{
	STAT status;						/* status */
} SVCL_UPLOAD;

/* --------------------------------- COMMON --------------------------------- */

typedef struct /* DATA_BLOCK */
{
	STAT status;						/* bytes */
	char data[MAX_DATA];				/* data */
} COMM_DATA_BLOCK;

typedef struct /* DATA_LIST */
{
	STAT status;						/* bytes */
	char data[MAX_LIST];				/* list */
} COMM_LIST_BLOCK;


typedef union
{
	CLSV_LOGIN			clsv_login;
	CLSV_PASSWD			clsv_passwd;
	CLSV_GET_TICKET		clsv_get_ticket;
	CLSV_USE_TICKET		clsv_use_ticket;
	CLSV_UPLOAD			clsv_upload;
	CLSV_LIST_USERS		clsv_list_users;
	CLSV_LIST_FILES		clsv_list_files;
	SVCL_LOGIN			svcl_login;
	SVCL_PASSWD			svcl_passwd;
	SVCL_GET_TICKET		svcl_get_ticket;
	SVCL_UPLOAD			svcl_upload;
	COMM_DATA_BLOCK		comm_data_block;
	COMM_LIST_BLOCK		comm_list_block;
} DATA;

typedef struct
{
	OPC opcode;						/* opcode */
	DATA data;						/* data */
} CLSV_BUFFER;

#endif
